﻿#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QCryptographicHash>
#include <QUuid>

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget), m_isLoggedIn(false)
{
    ui->setupUi(this);

    // This example supports RTSP video stream (others are not supported/no audio-video synchronization)
    QStringList urls;
    urls << "http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4";
    urls << "rtsp://admin:Admin123456@192.168.0.15:554/media/video1";
    ui->cboxUrl->addItems(urls);
    ui->cboxUrl->setCurrentIndex(0);
    
    // 初始化设备ID（使用MAC地址或者UUID）
    m_deviceId = QUuid::createUuid().toString(QUuid::WithoutBraces);

    // Initialize WebSocket client
    m_webSocketClient = new WebSocketClient(this);
    
    // Connect WebSocket signals and slots
    connect(m_webSocketClient, &WebSocketClient::connectionStateChanged, this, &Widget::onWebSocketConnectionStateChanged);
    connect(m_webSocketClient, &WebSocketClient::rtspUrlReceived, this, &Widget::onRtspUrlReceived);
    connect(m_webSocketClient, &WebSocketClient::errorOccurred, this, &Widget::onWebSocketError);
    
    // 连接登录相关信号槽
    connect(m_webSocketClient, &WebSocketClient::challengeReceived, this, &Widget::onChallengeReceived);
    connect(m_webSocketClient, &WebSocketClient::loginSuccess, this, &Widget::onLoginSuccess);
    connect(m_webSocketClient, &WebSocketClient::loginFailed, this, &Widget::onLoginFailed);
    
    // 初始化界面登录状态
    updateLoginStatus(false);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnSelect_clicked()
{
    QString fileName = QFileDialog::getOpenFileName();
    if (!fileName.isEmpty()) {
        ui->cboxUrl->addItem(fileName);
        ui->cboxUrl->lineEdit()->setText(fileName);
        if (ui->btnOpen->text() == QString("Open")) {
            on_btnOpen_clicked();
        }
    }
}

void Widget::on_btnOpen_clicked()
{
    if (ui->btnOpen->text() == QString("Open")) {
        ui->btnOpen->setText(QString("Close"));
        QString url = ui->cboxUrl->currentText().trimmed();
        ui->playWidget->setUrl(url);
        ui->playWidget->open();
    } else {
        ui->btnOpen->setText(QString("Open"));
        ui->playWidget->close();
    }
}

void Widget::on_btnConnectWs_clicked()
{
    if (!m_webSocketClient->isConnected()) {
        QString wsUrl = ui->lineEditWsUrl->text().trimmed();
        if (wsUrl.isEmpty()) {
            QMessageBox::warning(this, QString("Warning"), QString("WebSocket server address cannot be empty"));
            return;
        }
        
        m_webSocketClient->connectToServer(wsUrl);
        ui->btnConnectWs->setText(QString("Disconnect"));
    } else {
        m_webSocketClient->disconnectFromServer();
        ui->btnConnectWs->setText(QString("Connect Server"));
    }
}

void Widget::on_btnRequestRtsp_clicked()
{
    if (!m_webSocketClient->isConnected()) {
        QMessageBox::warning(this, QString("Warning"), QString("Please connect to WebSocket server first"));
        return;
    }
    
    QString cameraId = ui->lineEditCameraId->text().trimmed();
    if (cameraId.isEmpty()) {
        QMessageBox::warning(this, QString("Warning"), QString("Camera ID cannot be empty"));
        return;
    }
    
    m_webSocketClient->requestRtspUrl(cameraId);
}

void Widget::onWebSocketConnectionStateChanged(bool connected)
{
    if (connected) {
        ui->labelWsStatus->setText(QString("Connected"));
        ui->labelWsStatus->setStyleSheet(QString("color: green;"));
        ui->btnConnectWs->setText(QString("Disconnect"));
    } else {
        ui->labelWsStatus->setText(QString("Disconnected"));
        ui->labelWsStatus->setStyleSheet(QString("color: red;"));
        ui->btnConnectWs->setText(QString("Connect Server"));
    }
}

void Widget::onRtspUrlReceived(const QString &url, const QString &expiresAt)
{
    // Add the received RTSP URL to the dropdown
    ui->cboxUrl->addItem(url);
    ui->cboxUrl->setCurrentText(url);
    
    // Display expiration time
    if (!expiresAt.isEmpty()) {
        ui->labelUrlExpires->setText(QString("URL Expires: ") + expiresAt);
    }
    
    // Auto open video stream
    if (ui->btnOpen->text() == QString("Open")) {
        on_btnOpen_clicked();
    } else {
        // If already playing, close and reopen
        on_btnOpen_clicked();
        on_btnOpen_clicked();
    }
}

void Widget::onWebSocketError(const QString &errorMessage)
{
    QMessageBox::critical(this, QString("Error"), QString("WebSocket Error: ") + errorMessage);
}

// 生成密码凭证（SHA256(password + challenge)）
QString Widget::generateCredential(const QString &password, const QString &challenge)
{
    QByteArray combinedData = password.toUtf8() + challenge.toUtf8();
    QByteArray hash = QCryptographicHash::hash(combinedData, QCryptographicHash::Sha256);
    return hash.toHex();
}

// 更新界面登录状态
void Widget::updateLoginStatus(bool isLoggedIn, const QString &username)
{
    m_isLoggedIn = isLoggedIn;
    
    // 更新UI状态
    ui->btnLogin->setEnabled(!isLoggedIn);
    ui->btnLogout->setEnabled(isLoggedIn);
    ui->lineEditUsername->setEnabled(!isLoggedIn);
    ui->lineEditPassword->setEnabled(!isLoggedIn);
    ui->checkBoxRememberMe->setEnabled(!isLoggedIn);
    
    if (isLoggedIn) {
        ui->labelLoginStatus->setText(QString("已登录: %1").arg(username));
        ui->labelLoginStatus->setStyleSheet("color: green;");
        ui->lineEditUsername->setText(username);
        ui->lineEditPassword->clear();
    } else {
        ui->labelLoginStatus->setText("未登录");
        ui->labelLoginStatus->setStyleSheet("color: gray;");
    }
}

// 登录按钮点击事件
void Widget::on_btnLogin_clicked()
{
    if (!m_webSocketClient->isConnected()) {
        QMessageBox::warning(this, "警告", "请先连接WebSocket服务器");
        return;
    }
    
    QString username = ui->lineEditUsername->text().trimmed();
    QString password = ui->lineEditPassword->text();
    
    if (username.isEmpty()) {
        QMessageBox::warning(this, "警告", "用户名不能为空");
        return;
    }
    
    if (password.isEmpty()) {
        QMessageBox::warning(this, "警告", "密码不能为空");
        return;
    }
    
    // 首先获取挑战码
    m_webSocketClient->requestChallenge(username, m_deviceId);
}

// 登出按钮点击事件
void Widget::on_btnLogout_clicked()
{
    if (!m_webSocketClient->isConnected() || !m_isLoggedIn) {
        return;
    }
    
    m_webSocketClient->logout(m_deviceId, false);
    
    // 清除令牌和用户信息
    m_accessToken.clear();
    m_refreshToken.clear();
    m_userInfo = QJsonObject();
    
    // 更新界面状态
    updateLoginStatus(false);
}

// 收到挑战码
void Widget::onChallengeReceived(const QString &challenge, int expiresIn)
{
    // 保存挑战码，用于后续登录
    m_currentChallenge = challenge;
    
    // 获取用户输入
    QString username = ui->lineEditUsername->text().trimmed();
    QString password = ui->lineEditPassword->text();
    bool rememberMe = ui->checkBoxRememberMe->isChecked();
    
    // 生成凭证
    QString credential = generateCredential(password, challenge);
    
    // 发送登录请求
    m_webSocketClient->login(username, challenge, credential, m_deviceId, rememberMe);
}

// 登录成功
void Widget::onLoginSuccess(const QString &accessToken, const QString &refreshToken, const QJsonObject &userInfo)
{
    // 保存令牌和用户信息
    m_accessToken = accessToken;
    m_refreshToken = refreshToken;
    m_userInfo = userInfo;
    
    // 获取用户名
    QString username = userInfo.contains("username") ? 
                        userInfo["username"].toString() : 
                        ui->lineEditUsername->text().trimmed();
    
    // 更新界面状态
    updateLoginStatus(true, username);
    
    QMessageBox::information(this, "提示", "登录成功");
}

// 登录失败
void Widget::onLoginFailed(int errorCode, const QString &errorMessage)
{
    QMessageBox::warning(this, "登录失败", 
                        QString("错误码: %1\n错误信息: %2").arg(errorCode).arg(errorMessage));
}
